home *** CD-ROM | disk | FTP | other *** search
/ Resource Library: Multimedia / Resource Library: Multimedia.iso / maestro / source / displytl / xvtiff.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-06-15  |  28.7 KB  |  1,340 lines

  1. /*
  2.  * xvtiff.c - load routine for 'TIFF' format pictures
  3.  *
  4.  * LoadTIFF(fname, numcols)  -  load a TIFF file
  5.  */
  6.  
  7. #include "xvtiffio.h"
  8.  
  9. #ifndef _VA_LIST
  10. #define NEEDSARGS
  11. #endif
  12.  
  13. #include "xvimage.h"
  14.  
  15. #ifdef __GNUC__
  16. #include <stdarg.h>
  17. #else
  18. #include <varargs.h>
  19. #endif
  20.  
  21. static int loadPalette();
  22. static int loadColor();
  23. static int loadImage();
  24. static void _TIFFerr();
  25. static void _TIFFwarn();
  26.  
  27. static long filesize;
  28.  
  29.  
  30. /*******************************************/
  31. int LoadTIFF(fname,nc)
  32.      char *fname;
  33.      int   nc;
  34. /*******************************************/
  35. {
  36.   TIFF  *tif;
  37.   long   w, h;
  38.   short     bps, spp, photo, orient;
  39.   int     rv;
  40.   FILE  *fp;
  41.  
  42.  
  43.   /* open the stream to find out filesize (for info box) */
  44.   fp=fopen(fname,"r");
  45.   if (!fp) return 1;
  46.  
  47.   fseek(fp, 0L, 2);
  48.   filesize = ftell(fp);
  49.   fclose(fp);
  50.  
  51.  
  52.   /* open the stream, if necesary */
  53.   tif=TIFFOpen(fname,"r");
  54.   if (!tif) return 1;
  55.  
  56.   /* flip orientation so that image comes in X order */
  57.   TIFFGetFieldDefaulted(tif, TIFFTAG_ORIENTATION, &orient);
  58.   switch (orient) {
  59.   case ORIENTATION_TOPLEFT:
  60.   case ORIENTATION_TOPRIGHT:
  61.   case ORIENTATION_LEFTTOP:
  62.   case ORIENTATION_RIGHTTOP:
  63.     orient = ORIENTATION_BOTLEFT;
  64.     break;
  65.   case ORIENTATION_BOTRIGHT:
  66.   case ORIENTATION_BOTLEFT:
  67.   case ORIENTATION_RIGHTBOT:
  68.   case ORIENTATION_LEFTBOT:
  69.     orient = ORIENTATION_TOPLEFT;
  70.     break;
  71.   }
  72.   TIFFSetField(tif, TIFFTAG_ORIENTATION, orient);
  73.  
  74.   rv = 0;
  75.   TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &w);
  76.   TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &h);
  77.   TIFFGetFieldDefaulted(tif, TIFFTAG_BITSPERSAMPLE, &bps);
  78.   TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photo);
  79.   TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLESPERPIXEL, &spp);
  80.   if (spp == 1) {
  81.       rv = loadPalette(tif, w, h, photo, bps);
  82.   } else {
  83.       rv = loadColor(tif, w, h, photo, bps, nc);
  84.   }
  85.   TIFFClose(tif);
  86.  
  87.   return(rv);
  88. }  
  89.  
  90.  
  91. /*******************************************/
  92. static int loadPalette(tif, w, h, photo, bps)
  93. TIFF *tif;
  94. long  w,h;
  95. int   photo,bps;
  96. {
  97.   switch (photo) {
  98.   case PHOTOMETRIC_PALETTE:
  99.     sprintf(formatStr, "TIFF, %u-bit, palette format.  (%ld bytes)",
  100.         bps, filesize);
  101.     break;
  102.   case PHOTOMETRIC_MINISWHITE:
  103.   case PHOTOMETRIC_MINISBLACK:
  104.     sprintf(formatStr, "TIFF, %u-bit, %s format.  (%ld bytes)", 
  105.         bps,
  106.         photo == PHOTOMETRIC_MINISWHITE ? "min-is-white" :
  107.                                           "min-is-black",
  108.         filesize);
  109.     break;
  110.   }
  111.  
  112.   /* load up the XV global variables */
  113.   pic = (byte *) malloc(w*h);
  114.   if (!pic) FatalError("couldn't malloc 'pic'");
  115.  
  116.   pWIDE = w;  pHIGH = h;
  117.  
  118.   return !loadImage(tif, w, h, pic, 0);
  119. }
  120.  
  121. /*******************************************/
  122. static int loadColor(tif, w, h, photo, bps, nc)
  123. TIFF *tif;
  124. long  w,h;
  125. int   photo,bps,nc;
  126. {
  127.   byte *pic24;
  128.   int  rv;
  129.  
  130.   sprintf(formatStr, "TIFF, %u-bit, %s format.  (%ld bytes)", 
  131.       bps,
  132.       (photo == PHOTOMETRIC_RGB ?    "RGB" :
  133.        photo == PHOTOMETRIC_YCBCR ?    "YCbCr" :
  134.                     "???"),
  135.       filesize);
  136.  
  137.   /* allocate 24-bit image */
  138.   pic24 = (byte *) malloc(w*h*3);
  139.   if (!pic24) FatalError("couldn't malloc 'pic24'");
  140.  
  141.   if (loadImage(tif, w, h, pic24, 0))
  142.       rv = Conv24to8(pic24,w,h,nc);
  143.   else
  144.       rv = 1;
  145.   free(pic24);
  146.   return rv;
  147. }
  148.  
  149.  
  150. /*******************************************/
  151. static void _TIFFerr(module, fmt, ap)
  152. char *module;
  153. char *fmt;
  154. va_list ap;
  155. {
  156.   char buf[2048];
  157.   char *cp = buf;
  158.  
  159.   if (module != NULL) {
  160.     sprintf(cp, "%s: ", module);
  161.     cp = (char *) strchr(cp, '\0');
  162.   }
  163.  
  164.   vsprintf(cp, fmt, ap);
  165.   strcat(cp, ".");
  166.   printf("%s\n", buf);
  167. }
  168.  
  169. /*******************************************/
  170. static void _TIFFwarn(module, fmt, ap)
  171. char *module;
  172. char *fmt;
  173. va_list ap;
  174. {
  175.   char buf[2048];
  176.   char *cp = buf;
  177.  
  178.   if (module != NULL) {
  179.     sprintf(cp, "%s: ", module);
  180.     cp = (char *) strchr(cp, '\0');
  181.   }
  182.   strcpy(cp, "Warning, ");
  183.   cp = (char *) strchr(cp, '\0');
  184.   vsprintf(cp, fmt, ap);
  185.   strcat(cp, ".");
  186.   printf("%s\n", buf);
  187. }
  188.  
  189. #ifdef notdef
  190. typedef    unsigned char u_char;
  191. typedef    unsigned short u_short;
  192. typedef    unsigned int u_int;
  193. typedef    unsigned long u_long;
  194. #endif
  195.  
  196. typedef    byte RGBvalue;
  197.  
  198. static    u_long width, height;        /* image width & height */
  199. static    u_short bitspersample;
  200. static    u_short samplesperpixel;
  201. static    u_short photometric;
  202. static    u_short orientation;
  203. /* colormap for pallete images */
  204. static    u_short *redcmap, *greencmap, *bluecmap;
  205. static    int stoponerr;            /* stop on read error */
  206. static    char *filename;
  207. /* YCbCr support */
  208. static    u_short YCbCrHorizSampling;
  209. static    u_short YCbCrVertSampling;
  210. static    float *YCbCrCoeffs;
  211. static    u_long *refBlackWhite;
  212.  
  213. static    byte **BWmap;
  214. static    byte **PALmap;
  215.  
  216. static    int gt();
  217.  
  218. static int loadImage(tif, rwidth, rheight, raster, stop)
  219.     TIFF *tif;
  220.     u_long rwidth, rheight;
  221.     byte *raster;
  222.     int stop;
  223. {
  224.     int ok;
  225.     u_long width, height;
  226.  
  227.     TIFFGetFieldDefaulted(tif, TIFFTAG_BITSPERSAMPLE, &bitspersample);
  228.     switch (bitspersample) {
  229.     case 1: case 2: case 4:
  230.     case 8: case 16:
  231.         break;
  232.     default:
  233.         TIFFError(TIFFFileName(tif),
  234.             "Sorry, can not handle %d-bit pictures", bitspersample);
  235.         return (0);
  236.     }
  237.     TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel);
  238.     switch (samplesperpixel) {
  239.     case 1: case 3: case 4:
  240.         break;
  241.     default:
  242.         TIFFError(TIFFFileName(tif),
  243.             "Sorry, can not handle %d-channel images", samplesperpixel);
  244.         return (0);
  245.     }
  246.     if (!TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photometric)) {
  247.         switch (samplesperpixel) {
  248.         case 1:
  249.             photometric = PHOTOMETRIC_MINISBLACK;
  250.             break;
  251.         case 3: case 4:
  252.             photometric = PHOTOMETRIC_RGB;
  253.             break;
  254.         default:
  255.             TIFFError(TIFFFileName(tif),
  256.                 "Missing needed \"PhotometricInterpretation\" tag");
  257.             return (0);
  258.         }
  259.         TIFFError(TIFFFileName(tif),
  260.             "No \"PhotometricInterpretation\" tag, assuming %s\n",
  261.             photometric == PHOTOMETRIC_RGB ? "RGB" : "min-is-black");
  262.     }
  263.     /* XXX maybe should check photometric? */
  264.     TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width);
  265.     TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height);
  266.     /* XXX verify rwidth and rheight against width and height */
  267.     stoponerr = stop;
  268.     BWmap = NULL;
  269.     PALmap = NULL;
  270.     ok = gt(tif, rwidth, height, raster + (rheight-height)*rwidth);
  271.     if (BWmap)
  272.         free((char *)BWmap);
  273.     if (PALmap)
  274.         free((char *)PALmap);
  275.     return (ok);
  276. }
  277.  
  278. static int
  279. checkcmap(n, r, g, b)
  280.     int n;
  281.     u_short *r, *g, *b;
  282. {
  283.     while (n-- >= 0)
  284.         if (*r++ >= 256 || *g++ >= 256 || *b++ >= 256)
  285.             return (16);
  286.     TIFFWarning(filename, "Assuming 8-bit colormap");
  287.     return (8);
  288. }
  289.  
  290. static    gtTileContig();
  291. static    gtTileSeparate();
  292. static    gtStripContig();
  293. static    gtStripSeparate();
  294. static    void initYCbCrConversion();
  295.  
  296. static int
  297. gt(tif, w, h, raster)
  298.     TIFF *tif;
  299.     int w, h;
  300.     u_long *raster;
  301. {
  302.     u_short minsamplevalue, maxsamplevalue, planarconfig;
  303.     RGBvalue *Map;
  304.     int bpp = 1, e;
  305.     int x, range;
  306.  
  307.     TIFFGetFieldDefaulted(tif, TIFFTAG_MINSAMPLEVALUE, &minsamplevalue);
  308.     TIFFGetFieldDefaulted(tif, TIFFTAG_MAXSAMPLEVALUE, &maxsamplevalue);
  309.     Map = NULL;
  310.     switch (photometric) {
  311.     case PHOTOMETRIC_YCBCR:
  312.         TIFFGetFieldDefaulted(tif, TIFFTAG_YCBCRCOEFFICIENTS,
  313.             &YCbCrCoeffs);
  314.         TIFFGetFieldDefaulted(tif, TIFFTAG_YCBCRSUBSAMPLING,
  315.             &YCbCrHorizSampling, &YCbCrVertSampling);
  316.         TIFFGetFieldDefaulted(tif, TIFFTAG_REFERENCEBLACKWHITE,
  317.             &refBlackWhite);
  318.         initYCbCrConversion();
  319.         /* fall thru... */
  320.     case PHOTOMETRIC_RGB:
  321.         bpp *= 3;
  322.         if (minsamplevalue == 0 && maxsamplevalue == 255)
  323.             break;
  324.         /* fall thru... */
  325.     case PHOTOMETRIC_MINISBLACK:
  326.     case PHOTOMETRIC_MINISWHITE:
  327.         range = maxsamplevalue - minsamplevalue;
  328.         Map = (RGBvalue *)malloc((range + 1) * sizeof (RGBvalue));
  329.         if (Map == NULL) {
  330.             TIFFError(filename,
  331.                 "No space for photometric conversion table");
  332.             return (0);
  333.         }
  334.         if (photometric == PHOTOMETRIC_MINISWHITE) {
  335.             for (x = 0; x <= range; x++)
  336.                 r[x] = g[x] = b[x] =
  337.                     Map[x] = (255*(range-x))/range;
  338.         } else {
  339.             for (x = 0; x <= range; x++)
  340.                 r[x] = g[x] = b[x] = Map[x] = (255*x)/range;
  341.         }
  342.         if (photometric != PHOTOMETRIC_RGB && bitspersample <= 8) {
  343.             /*
  344.              * Use photometric mapping table to construct
  345.              * unpacking tables for samples <= 8 bits.
  346.              */
  347.             if (!makebwmap())
  348.                 return (0);
  349.             /* no longer need Map, free it */
  350.             free((char *)Map);
  351.             Map = NULL;
  352.         }
  353.         break;
  354.     case PHOTOMETRIC_PALETTE:
  355.         if (!TIFFGetField(tif, TIFFTAG_COLORMAP,
  356.                   &redcmap, &greencmap, &bluecmap)) {
  357.             TIFFError(filename,
  358.                 "Missing required \"Colormap\" tag");
  359.             return (0);
  360.         }
  361.         /*
  362.          * Convert 16-bit colormap to 8-bit (unless it looks
  363.          * like an old-style 8-bit colormap).
  364.          */
  365.         range = (1<<bitspersample)-1;
  366.         if (checkcmap(range, redcmap, greencmap, bluecmap) == 16) {
  367. #define    CVT(x)        (((x) * 255) / ((1L<<16)-1))
  368.             for (x = range; x >= 0; x--) {
  369.                 r[x] = CVT(redcmap[x]);
  370.                 g[x] = CVT(greencmap[x]);
  371.                 b[x] = CVT(bluecmap[x]);
  372.             }
  373.         } else {
  374.             for (x = range; x >= 0; x--) {
  375.                 r[x] = redcmap[x];
  376.                 g[x] = greencmap[x];
  377.                 b[x] = bluecmap[x];
  378.             }
  379.         }
  380.         if (bitspersample <= 8) {
  381.             /*
  382.              * Use mapping table to construct
  383.              * unpacking tables for samples < 8 bits.
  384.              */
  385.             if (!makecmap())
  386.                 return (0);
  387.         }
  388.         break;
  389.     default:
  390.         TIFFError(filename, "Unknown photometric tag %u", photometric);
  391.         return (0);
  392.     }
  393.     TIFFGetField(tif, TIFFTAG_PLANARCONFIG, &planarconfig);
  394.     if (planarconfig == PLANARCONFIG_SEPARATE && samplesperpixel > 1) {
  395.         e = TIFFIsTiled(tif) ?
  396.             gtTileSeparate(tif, raster, Map, h, w, bpp) :
  397.             gtStripSeparate(tif, raster, Map, h, w, bpp);
  398.     } else {
  399.         e = TIFFIsTiled(tif) ? 
  400.             gtTileContig(tif, raster, Map, h, w, bpp) :
  401.             gtStripContig(tif, raster, Map, h, w, bpp);
  402.     }
  403.     if (Map)
  404.         free((char *)Map);
  405.     return (e);
  406. }
  407.  
  408. u_long
  409. setorientation(tif, h)
  410.     TIFF *tif;
  411.     u_long h;
  412. {
  413.     u_long y;
  414.  
  415.     TIFFGetFieldDefaulted(tif, TIFFTAG_ORIENTATION, &orientation);
  416.     switch (orientation) {
  417.     case ORIENTATION_BOTRIGHT:
  418.     case ORIENTATION_RIGHTBOT:    /* XXX */
  419.     case ORIENTATION_LEFTBOT:    /* XXX */
  420.         TIFFWarning(filename, "using bottom-left orientation");
  421.         orientation = ORIENTATION_BOTLEFT;
  422.         /* fall thru... */
  423.     case ORIENTATION_BOTLEFT:
  424.         y = 0;
  425.         break;
  426.     case ORIENTATION_TOPRIGHT:
  427.     case ORIENTATION_RIGHTTOP:    /* XXX */
  428.     case ORIENTATION_LEFTTOP:    /* XXX */
  429.     default:
  430.         TIFFWarning(filename, "using top-left orientation");
  431.         orientation = ORIENTATION_TOPLEFT;
  432.         /* fall thru... */
  433.     case ORIENTATION_TOPLEFT:
  434.         y = h-1;
  435.         break;
  436.     }
  437.     return (y);
  438. }
  439.  
  440. #if USE_PROTOTYPES
  441. typedef void (*tileContigRoutine)
  442.     (byte*, u_char*, RGBvalue*, u_long, u_long, int, int);
  443. static tileContigRoutine pickTileContigCase(RGBvalue*);
  444. #else
  445. typedef void (*tileContigRoutine)();
  446. static tileContigRoutine pickTileContigCase();
  447. #endif
  448.  
  449. /*
  450.  * Get an tile-organized image that has
  451.  *    PlanarConfiguration contiguous if SamplesPerPixel > 1
  452.  * or
  453.  *    SamplesPerPixel == 1
  454.  */    
  455. static int
  456. gtTileContig(tif, raster, Map, h, w, bpp)
  457.     TIFF *tif;
  458.     byte *raster;
  459.     RGBvalue *Map;
  460.     u_long h, w;
  461.     int bpp;
  462. {
  463.     u_long col, row, y;
  464.     u_long tw, th;
  465.     u_char *buf;
  466.     int fromskew, toskew;
  467.     u_int nrow;
  468.     tileContigRoutine put;
  469.  
  470.     put = pickTileContigCase(Map);
  471.     if (put == 0)
  472.         return (0);
  473.     buf = (u_char *)malloc(TIFFTileSize(tif));
  474.     if (buf == 0) {
  475.         TIFFError(filename, "No space for tile buffer");
  476.         return (0);
  477.     }
  478.     TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tw);
  479.     TIFFGetField(tif, TIFFTAG_TILELENGTH, &th);
  480.     y = setorientation(tif, h);
  481.     toskew = (orientation == ORIENTATION_TOPLEFT ? -tw + -w : -tw + w);
  482.     for (row = 0; row < h; row += th) {
  483.         nrow = (row + th > h ? h - row : th);
  484.         for (col = 0; col < w; col += tw) {
  485.             if (TIFFReadTile(tif, buf, col, row, 0, 0) < 0 &&
  486.                 stoponerr)
  487.                 break;
  488.             if (col + tw > w) {
  489.                 /*
  490.                  * Tile is clipped horizontally.  Calculate
  491.                  * visible portion and skewing factors.
  492.                  */
  493.                 u_long npix = w - col;
  494.                 fromskew = tw - npix;
  495.                 (*put)(raster + (y*w + col)*bpp, buf, Map,
  496.                     npix, nrow,
  497.                     fromskew, (toskew + fromskew)*bpp);
  498.             } else
  499.                 (*put)(raster + (y*w + col)*bpp, buf, Map,
  500.                     tw, nrow,
  501.                     0, toskew*bpp);
  502.         }
  503.         y += (orientation == ORIENTATION_TOPLEFT ? -nrow : nrow);
  504.     }
  505.     free(buf);
  506.     return (1);
  507. }
  508.  
  509. #if USE_PROTOTYPES
  510. typedef void (*tileSeparateRoutine)
  511.     (byte*, u_char*, u_char*, u_char*, RGBvalue*, u_long, u_long, int, int);
  512. static tileSeparateRoutine pickTileSeparateCase(RGBvalue*);
  513. #else
  514. typedef void (*tileSeparateRoutine)();
  515. static tileSeparateRoutine pickTileSeparateCase();
  516. #endif
  517.  
  518. /*
  519.  * Get an tile-organized image that has
  520.  *     SamplesPerPixel > 1
  521.  *     PlanarConfiguration separated
  522.  * We assume that all such images are RGB.
  523.  */    
  524. static int
  525. gtTileSeparate(tif, raster, Map, h, w, bpp)
  526.     TIFF *tif;
  527.     byte *raster;
  528.     RGBvalue *Map;
  529.     u_long h, w;
  530.     int bpp;
  531. {
  532.     u_long col, row, y;
  533.     u_long tw, th;
  534.     u_char *buf;
  535.     u_char *r, *g, *b;
  536.     int tilesize;
  537.     int fromskew, toskew;
  538.     u_int nrow;
  539.     tileSeparateRoutine put;
  540.  
  541.     put = pickTileSeparateCase(Map);
  542.     if (put == 0)
  543.         return (0);
  544.     tilesize = TIFFTileSize(tif);
  545.     buf = (u_char *)malloc(3*tilesize);
  546.     if (buf == 0) {
  547.         TIFFError(filename, "No space for tile buffer");
  548.         return (0);
  549.     }
  550.     r = buf;
  551.     g = r + tilesize;
  552.     b = g + tilesize;
  553.     TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tw);
  554.     TIFFGetField(tif, TIFFTAG_TILELENGTH, &th);
  555.     y = setorientation(tif, h);
  556.     toskew = (orientation == ORIENTATION_TOPLEFT ? -tw + -w : -tw + w);
  557.     for (row = 0; row < h; row += th) {
  558.         nrow = (row + th > h ? h - row : th);
  559.         for (col = 0; col < w; col += tw) {
  560.             if (TIFFReadTile(tif, r, col, row,0,0) < 0 && stoponerr)
  561.                 break;
  562.             if (TIFFReadTile(tif, g, col, row,0,1) < 0 && stoponerr)
  563.                 break;
  564.             if (TIFFReadTile(tif, b, col, row,0,2) < 0 && stoponerr)
  565.                 break;
  566.             if (col + tw > w) {
  567.                 /*
  568.                  * Tile is clipped horizontally.  Calculate
  569.                  * visible portion and skewing factors.
  570.                  */
  571.                 u_long npix = w - col;
  572.                 fromskew = tw - npix;
  573.                 (*put)(raster + (y*w + col)*bpp, r, g, b, Map,
  574.                     npix, nrow,
  575.                     fromskew, (toskew + fromskew)*bpp);
  576.             } else
  577.                 (*put)(raster + (y*w + col)*bpp, r, g, b, Map,
  578.                     tw, nrow, 0, toskew*bpp);
  579.         }
  580.         y += (orientation == ORIENTATION_TOPLEFT ? -nrow : nrow);
  581.     }
  582.     free(buf);
  583.     return (1);
  584. }
  585.  
  586. /*
  587.  * Get a strip-organized image that has
  588.  *    PlanarConfiguration contiguous if SamplesPerPixel > 1
  589.  * or
  590.  *    SamplesPerPixel == 1
  591.  */    
  592. static int
  593. gtStripContig(tif, raster, Map, h, w, bpp)
  594.     TIFF *tif;
  595.     byte *raster;
  596.     RGBvalue *Map;
  597.     u_long h, w;
  598.     int bpp;
  599. {
  600.     u_long row, y, nrow;
  601.     u_char *buf;
  602.     tileContigRoutine put;
  603.     u_long rowsperstrip;
  604.     u_long imagewidth;
  605.     int scanline;
  606.     int fromskew, toskew;
  607.  
  608.     put = pickTileContigCase(Map);
  609.     if (put == 0)
  610.         return (0);
  611.     buf = (u_char *)malloc(TIFFStripSize(tif));
  612.     if (buf == 0) {
  613.         TIFFError(filename, "No space for strip buffer");
  614.         return (0);
  615.     }
  616.     y = setorientation(tif, h);
  617.     toskew = (orientation == ORIENTATION_TOPLEFT ? -w + -w : -w + w);
  618.     TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
  619.     TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &imagewidth);
  620.     scanline = TIFFScanlineSize(tif);
  621.     fromskew = (w < imagewidth ? imagewidth - w : 0);
  622.     for (row = 0; row < h; row += rowsperstrip) {
  623.         nrow = (row + rowsperstrip > h ? h - row : rowsperstrip);
  624.         if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, row, 0),
  625.             buf, nrow*scanline) < 0 && stoponerr)
  626.             break;
  627.         (*put)(raster + y*w*bpp, buf, Map, w, nrow,
  628.             fromskew, toskew*bpp);
  629.         y += (orientation == ORIENTATION_TOPLEFT ? -nrow : nrow);
  630.     }
  631.     free(buf);
  632.     return (1);
  633. }
  634.  
  635. /*
  636.  * Get a strip-organized image with
  637.  *     SamplesPerPixel > 1
  638.  *     PlanarConfiguration separated
  639.  * We assume that all such images are RGB.
  640.  */
  641. static int
  642. gtStripSeparate(tif, raster, Map, h, w, bpp)
  643.     TIFF *tif;
  644.     byte *raster;
  645.     register RGBvalue *Map;
  646.     u_long h, w;
  647.     int bpp;
  648. {
  649.     u_char *buf;
  650.     u_char *r, *g, *b;
  651.     u_long row, y, nrow;
  652.     int scanline;
  653.     tileSeparateRoutine put;
  654.     u_long rowsperstrip;
  655.     u_long imagewidth;
  656.     u_int stripsize;
  657.     int fromskew, toskew;
  658.  
  659.     stripsize = TIFFStripSize(tif);
  660.     r = buf = (u_char *)malloc(3*stripsize);
  661.     if (buf == 0)
  662.         return (0);
  663.     g = r + stripsize;
  664.     b = g + stripsize;
  665.     put = pickTileSeparateCase(Map);
  666.     if (put == 0) {
  667.         TIFFError(filename, "Can not handle format");
  668.         return (0);
  669.     }
  670.     y = setorientation(tif, h);
  671.     toskew = (orientation == ORIENTATION_TOPLEFT ? -w + -w : -w + w);
  672.     TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
  673.     TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &imagewidth);
  674.     scanline = TIFFScanlineSize(tif);
  675.     fromskew = (w < imagewidth ? imagewidth - w : 0);
  676.     for (row = 0; row < h; row += rowsperstrip) {
  677.         nrow = (row + rowsperstrip > h ? h - row : rowsperstrip);
  678.         if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, row, 0),
  679.             r, nrow*scanline) < 0 && stoponerr)
  680.             break;
  681.         if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, row, 1),
  682.             g, nrow*scanline) < 0 && stoponerr)
  683.             break;
  684.         if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, row, 2),
  685.             b, nrow*scanline) < 0 && stoponerr)
  686.             break;
  687.         (*put)(raster + y*w*bpp, r, g, b, Map, w, nrow,
  688.             fromskew, toskew*bpp);
  689.         y += (orientation == ORIENTATION_TOPLEFT ? -nrow : nrow);
  690.     }
  691.     free(buf);
  692.     return (1);
  693. }
  694.  
  695. /*
  696.  * Greyscale images with less than 8 bits/sample are handled
  697.  * with a table to avoid lots of shifts and masks.  The table
  698.  * is setup so that put*bwtile (below) can retrieve 8/bitspersample
  699.  * pixel values simply by indexing into the table with one
  700.  * number.
  701.  */
  702. int makebwmap()
  703. {
  704.     register int i;
  705.     int nsamples = 8 / bitspersample;
  706.     register byte *p;
  707.  
  708.     BWmap = (byte **)malloc(
  709.         256*sizeof (byte *)+(256*nsamples*sizeof(byte)));
  710.     if (BWmap == NULL) {
  711.         TIFFError(filename, "No space for B&W mapping table");
  712.         return (0);
  713.     }
  714.     p = (byte *)(BWmap + 256);
  715.     for (i = 0; i < 256; i++) {
  716.         BWmap[i] = p;
  717.         switch (bitspersample) {
  718. #define    GREY(x)    *p++ = x;
  719.         case 1:
  720.             GREY(i>>7);
  721.             GREY((i>>6)&1);
  722.             GREY((i>>5)&1);
  723.             GREY((i>>4)&1);
  724.             GREY((i>>3)&1);
  725.             GREY((i>>2)&1);
  726.             GREY((i>>1)&1);
  727.             GREY(i&1);
  728.             break;
  729.         case 2:
  730.             GREY(i>>6);
  731.             GREY((i>>4)&3);
  732.             GREY((i>>2)&3);
  733.             GREY(i&3);
  734.             break;
  735.         case 4:
  736.             GREY(i>>4);
  737.             GREY(i&0xf);
  738.             break;
  739.         case 8:
  740.             GREY(i);
  741.             break;
  742.         }
  743. #undef    GREY
  744.     }
  745.     return (1);
  746. }
  747.  
  748. /*
  749.  * Palette images with <= 8 bits/sample are handled
  750.  * with a table to avoid lots of shifts and masks.  The table
  751.  * is setup so that put*cmaptile (below) can retrieve 8/bitspersample
  752.  * pixel values simply by indexing into the table with one
  753.  * number.
  754.  */
  755. int makecmap()
  756. {
  757.     register int i;
  758.     int nsamples = 8 / bitspersample;
  759.     register byte *p;
  760.  
  761.     PALmap = (byte **)MyMalloc(
  762.         256*sizeof (byte *)+(256*nsamples*sizeof(byte)));
  763.     if (PALmap == NULL) {
  764.         TIFFError(filename, "No space for Palette mapping table");
  765.         return (0);
  766.     }
  767.     p = (byte *)(PALmap + 256);
  768.     for (i = 0; i < 256; i++) {
  769.         PALmap[i] = p;
  770. #define    CMAP(x)    *p++ = x;
  771.         switch (bitspersample) {
  772.             register RGBvalue c;
  773.         case 1:
  774.             CMAP(i>>7);
  775.             CMAP((i>>6)&1);
  776.             CMAP((i>>5)&1);
  777.             CMAP((i>>4)&1);
  778.             CMAP((i>>3)&1);
  779.             CMAP((i>>2)&1);
  780.             CMAP((i>>1)&1);
  781.             CMAP(i&1);
  782.             break;
  783.         case 2:
  784.             CMAP(i>>6);
  785.             CMAP((i>>4)&3);
  786.             CMAP((i>>2)&3);
  787.             CMAP(i&3);
  788.             break;
  789.         case 4:
  790.             CMAP(i>>4);
  791.             CMAP(i&0xf);
  792.             break;
  793.         case 8:
  794.             CMAP(i);
  795.             break;
  796.         }
  797. #undef CMAP
  798.     }
  799.     return (1);
  800. }
  801.  
  802. /*
  803.  * The following routines move decoded data returned
  804.  * from the TIFF library into rasters filled with packed
  805.  * ABGR pixels (i.e. suitable for passing to lrecwrite.)
  806.  *
  807.  * The routines have been created according to the most
  808.  * important cases and optimized.  pickTileContigCase and
  809.  * pickTileSeparateCase analyze the parameters and select
  810.  * the appropriate "put" routine to use.
  811.  */
  812. #define    REPEAT8(op)    REPEAT4(op); REPEAT4(op)
  813. #define    REPEAT4(op)    REPEAT2(op); REPEAT2(op)
  814. #define    REPEAT2(op)    op; op
  815. #define    CASE8(x,op)                \
  816.     switch (x) {                \
  817.     case 7: op; case 6: op; case 5: op;    \
  818.     case 4: op; case 3: op; case 2: op;    \
  819.     case 1: op;                \
  820.     }
  821. #define    CASE4(x,op)    switch (x) { case 3: op; case 2: op; case 1: op; }
  822.  
  823. #define    UNROLL8(w, op1, op2) {        \
  824.     register u_long x;        \
  825.     for (x = w; x >= 8; x -= 8) {    \
  826.         op1;            \
  827.         REPEAT8(op2);        \
  828.     }                \
  829.     if (x > 0) {            \
  830.         op1;            \
  831.         CASE8(x,op2);        \
  832.     }                \
  833. }
  834. #define    UNROLL4(w, op1, op2) {        \
  835.     register u_long x;        \
  836.     for (x = w; x >= 4; x -= 4) {    \
  837.         op1;            \
  838.         REPEAT4(op2);        \
  839.     }                \
  840.     if (x > 0) {            \
  841.         op1;            \
  842.         CASE4(x,op2);        \
  843.     }                \
  844. }
  845. #define    UNROLL2(w, op1, op2) {        \
  846.     register u_long x;        \
  847.     for (x = w; x >= 2; x -= 2) {    \
  848.         op1;            \
  849.         REPEAT2(op2);        \
  850.     }                \
  851.     if (x) {            \
  852.         op1;            \
  853.         op2;            \
  854.     }                \
  855. }
  856.             
  857.  
  858. #define    SKEW(r,g,b,skew)    { r += skew; g += skew; b += skew; }
  859.  
  860. /*
  861.  * 8-bit palette => colormap/RGB
  862.  */
  863. static void
  864. put8bitcmaptile(cp, pp, Map, w, h, fromskew, toskew)
  865.     register byte *cp;
  866.     register u_char *pp;
  867.     RGBvalue *Map;
  868.     u_long w, h;
  869.     int fromskew, toskew;
  870. {
  871.     while (h-- > 0) {
  872.         UNROLL8(w,, *cp++ = PALmap[*pp++][0]);
  873.         cp += toskew;
  874.         pp += fromskew;
  875.     }
  876. }
  877.  
  878. /*
  879.  * 4-bit palette => colormap/RGB
  880.  */
  881. static void
  882. put4bitcmaptile(cp, pp, Map, w, h, fromskew, toskew)
  883.     register byte *cp;
  884.     register u_char *pp;
  885.     register RGBvalue *Map;
  886.     u_long w, h;
  887.     int fromskew, toskew;
  888. {
  889.     register byte *bw;
  890.  
  891.     fromskew /= 2;
  892.     while (h-- > 0) {
  893.         UNROLL2(w, bw = PALmap[*pp++], *cp++ = *bw++);
  894.         cp += toskew;
  895.         pp += fromskew;
  896.     }
  897. }
  898.  
  899. /*
  900.  * 2-bit palette => colormap/RGB
  901.  */
  902. static void
  903. put2bitcmaptile(cp, pp, Map, w, h, fromskew, toskew)
  904.     register byte *cp;
  905.     register u_char *pp;
  906.     register RGBvalue *Map;
  907.     u_long w, h;
  908.     int fromskew, toskew;
  909. {
  910.     register byte *bw;
  911.  
  912.     fromskew /= 4;
  913.     while (h-- > 0) {
  914.         UNROLL4(w, bw = PALmap[*pp++], *cp++ = *bw++);
  915.         cp += toskew;
  916.         pp += fromskew;
  917.     }
  918. }
  919.  
  920. /*
  921.  * 1-bit palette => colormap/RGB
  922.  */
  923. static void
  924. put1bitcmaptile(cp, pp, Map, w, h, fromskew, toskew)
  925.     register byte *cp;
  926.     register u_char *pp;
  927.     register RGBvalue *Map;
  928.     u_long w, h;
  929.     int fromskew, toskew;
  930. {
  931.     register byte *bw;
  932.  
  933.     fromskew /= 8;
  934.     while (h-- > 0) {
  935.         UNROLL8(w, bw = PALmap[*pp++], *cp++ = *bw++);
  936.         cp += toskew;
  937.         pp += fromskew;
  938.     }
  939. }
  940.  
  941. /*
  942.  * 8-bit greyscale => colormap/RGB
  943.  */
  944. static void
  945. putgreytile(cp, pp, Map, w, h, fromskew, toskew)
  946.     register byte *cp;
  947.     register u_char *pp;
  948.     RGBvalue *Map;
  949.     u_long w, h;
  950.     int fromskew, toskew;
  951. {
  952.     while (h-- > 0) {
  953.         register u_long x;
  954.         for (x = w; x-- > 0;)
  955.             *cp++ = BWmap[*pp++][0];
  956.         cp += toskew;
  957.         pp += fromskew;
  958.     }
  959. }
  960.  
  961. /*
  962.  * 1-bit bilevel => colormap/RGB
  963.  */
  964. static void
  965. put1bitbwtile(cp, pp, Map, w, h, fromskew, toskew)
  966.     byte *cp;
  967.     u_char *pp;
  968.     RGBvalue **Map;
  969.     u_long w, h;
  970.     int fromskew, toskew;
  971. {
  972.     register byte *bw;
  973.  
  974.     fromskew /= 8;
  975.     while (h-- > 0) {
  976.         UNROLL8(w, bw = BWmap[*pp++], *cp++ = *bw++);
  977.         cp += toskew;
  978.         pp += fromskew;
  979.     }
  980. }
  981.  
  982. /*
  983.  * 2-bit greyscale => colormap/RGB
  984.  */
  985. static void
  986. put2bitbwtile(cp, pp, Map, w, h, fromskew, toskew)
  987.     byte *cp;
  988.     u_char *pp;
  989.     RGBvalue **Map;
  990.     u_long w, h;
  991.     int fromskew, toskew;
  992. {
  993.     register byte *bw;
  994.  
  995.     fromskew /= 4;
  996.     while (h-- > 0) {
  997.         UNROLL4(w, bw = BWmap[*pp++], *cp++ = *bw++);
  998.         cp += toskew;
  999.         pp += fromskew;
  1000.     }
  1001. }
  1002.  
  1003. /*
  1004.  * 4-bit greyscale => colormap/RGB
  1005.  */
  1006. static void
  1007. put4bitbwtile(cp, pp, Map, w, h, fromskew, toskew)
  1008.     byte *cp;
  1009.     u_char *pp;
  1010.     RGBvalue **Map;
  1011.     u_long w, h;
  1012.     int fromskew, toskew;
  1013. {
  1014.     register byte *bw;
  1015.  
  1016.     fromskew /= 2;
  1017.     while (h-- > 0) {
  1018.         UNROLL2(w, bw = BWmap[*pp++], *cp++ = *bw++);
  1019.         cp += toskew;
  1020.         pp += fromskew;
  1021.     }
  1022. }
  1023.  
  1024. /*
  1025.  * 8-bit packed samples => RGB
  1026.  */
  1027. static void
  1028. putRGBcontig8bittile(cp, pp, Map, w, h, fromskew, toskew)
  1029.     register byte *cp;
  1030.     register u_char *pp;
  1031.     register RGBvalue *Map;
  1032.     u_long w, h;
  1033.     int fromskew, toskew;
  1034. {
  1035.     fromskew *= samplesperpixel;
  1036.     if (Map) {
  1037.         while (h-- > 0) {
  1038.             register u_long x;
  1039.             for (x = w; x-- > 0;) {
  1040.                 *cp++ = Map[pp[0]];
  1041.                 *cp++ = Map[pp[1]];
  1042.                 *cp++ = Map[pp[2]];
  1043.                 pp += samplesperpixel;
  1044.             }
  1045.             pp += fromskew;
  1046.             cp += toskew;
  1047.         }
  1048.     } else {
  1049.         while (h-- > 0) {
  1050.             UNROLL8(w,,
  1051.                 *cp++ = pp[0];
  1052.                 *cp++ = pp[1];
  1053.                 *cp++ = pp[2];
  1054.                 pp += samplesperpixel);
  1055.             cp += toskew;
  1056.             pp += fromskew;
  1057.         }
  1058.     }
  1059. }
  1060.  
  1061. /*
  1062.  * 16-bit packed samples => RGB
  1063.  */
  1064. static void
  1065. putRGBcontig16bittile(cp, pp, Map, w, h, fromskew, toskew)
  1066.     register byte *cp;
  1067.     register u_short *pp;
  1068.     register RGBvalue *Map;
  1069.     u_long w, h;
  1070.     int fromskew, toskew;
  1071. {
  1072.     register u_int x;
  1073.  
  1074.     fromskew *= samplesperpixel;
  1075.     if (Map) {
  1076.         while (h-- > 0) {
  1077.             for (x = w; x-- > 0;) {
  1078.                 *cp++ = Map[pp[0]];
  1079.                 *cp++ = Map[pp[1]];
  1080.                 *cp++ = Map[pp[2]];
  1081.                 pp += samplesperpixel;
  1082.             }
  1083.             cp += toskew;
  1084.             pp += fromskew;
  1085.         }
  1086.     } else {
  1087.         while (h-- > 0) {
  1088.             for (x = w; x-- > 0;) {
  1089.                 *cp++ = pp[0];
  1090.                 *cp++ = pp[1];
  1091.                 *cp++ = pp[2];
  1092.                 pp += samplesperpixel;
  1093.             }
  1094.             cp += toskew;
  1095.             pp += fromskew;
  1096.         }
  1097.     }
  1098. }
  1099.  
  1100. /*
  1101.  * 8-bit unpacked samples => RGB
  1102.  */
  1103. static void
  1104. putRGBseparate8bittile(cp, r, g, b, Map, w, h, fromskew, toskew)
  1105.     register byte *cp;
  1106.     register u_char *r, *g, *b;
  1107.     register RGBvalue *Map;
  1108.     u_long w, h;
  1109.     int fromskew, toskew;
  1110.  
  1111. {
  1112.     if (Map) {
  1113.         while (h-- > 0) {
  1114.             register u_long x;
  1115.             for (x = w; x > 0; x--) {
  1116.                 *cp++ = Map[*r++];
  1117.                 *cp++ = Map[*g++];
  1118.                 *cp++ = Map[*b++];
  1119.             }
  1120.             SKEW(r, g, b, fromskew);
  1121.             cp += toskew;
  1122.         }
  1123.     } else {
  1124.         while (h-- > 0) {
  1125.             UNROLL8(w,,
  1126.                 *cp++ = *r++;
  1127.                 *cp++ = *g++;
  1128.                 *cp++ = *b++;
  1129.             );
  1130.             SKEW(r, g, b, fromskew);
  1131.             cp += toskew;
  1132.         }
  1133.     }
  1134. }
  1135.  
  1136. /*
  1137.  * 16-bit unpacked samples => RGB
  1138.  */
  1139. static void
  1140. putRGBseparate16bittile(cp, r, g, b, Map, w, h, fromskew, toskew)
  1141.     register byte *cp;
  1142.     register u_short *r, *g, *b;
  1143.     register RGBvalue *Map;
  1144.     u_long w, h;
  1145.     int fromskew, toskew;
  1146. {
  1147.     register u_long x;
  1148.  
  1149.     if (Map) {
  1150.         while (h-- > 0) {
  1151.             for (x = w; x > 0; x--) {
  1152.                 *cp++ = Map[*r++];
  1153.                 *cp++ = Map[*g++];
  1154.                 *cp++ = Map[*b++];
  1155.             }
  1156.             SKEW(r, g, b, fromskew);
  1157.             cp += toskew;
  1158.         }
  1159.     } else {
  1160.         while (h-- > 0) {
  1161.             for (x = 0; x < w; x++) {
  1162.                 *cp++ = *r++;
  1163.                 *cp++ = *g++;
  1164.                 *cp++ = *b++;
  1165.             }
  1166.             SKEW(r, g, b, fromskew);
  1167.             cp += toskew;
  1168.         }
  1169.     }
  1170. }
  1171.  
  1172. #define    Code2V(c, RB, RW, CR)    ((((c)-(int)RB)*(float)CR)/(float)(RW-RB))
  1173. #define    CLAMP(f,min,max) \
  1174.     (int)((f)+.5 < (min) ? (min) : (f)+.5 > (max) ? (max) : (f)+.5)
  1175.  
  1176. #define    LumaRed        YCbCrCoeffs[0]
  1177. #define    LumaGreen    YCbCrCoeffs[1]
  1178. #define    LumaBlue    YCbCrCoeffs[2]
  1179.  
  1180. static    float D1, D2;
  1181. static    float D3, D4;
  1182.  
  1183. static void
  1184. initYCbCrConversion()
  1185. {
  1186.     D1 = 2 - 2*LumaRed;
  1187.     D2 = D1*LumaRed / LumaGreen;
  1188.     D3 = 2 - 2*LumaBlue;
  1189.     D4 = D2*LumaBlue / LumaGreen;
  1190. }
  1191.  
  1192. static void
  1193. putRGBContigYCbCrClump(cp, pp, cw, ch, w, n, fromskew, toskew)
  1194.     register byte *cp;
  1195.     register u_char *pp;
  1196.     int cw, ch;
  1197.     u_long w;
  1198.     int n, fromskew, toskew;
  1199. {
  1200.     float Cb, Cr;
  1201.     int j, k;
  1202.  
  1203.     Cb = Code2V(pp[n],   refBlackWhite[2], refBlackWhite[3], 127);
  1204.     Cr = Code2V(pp[n+1], refBlackWhite[4], refBlackWhite[5], 127);
  1205.     for (j = 0; j < ch; j++) {
  1206.         for (k = 0; k < cw; k++) {
  1207.             float Y, R, G, B;
  1208.             Y = Code2V(*pp++,
  1209.                 refBlackWhite[0], refBlackWhite[1], 255);
  1210.             R = Y + Cr*D1;
  1211.             B = Y + Cb*D3;
  1212.             G = Y - Cb*D4 - Cr*D2;
  1213.             cp[3*k+0] = CLAMP(R,0,255);
  1214.             cp[3*k+1] = CLAMP(G,0,255);
  1215.             cp[3*k+2] = CLAMP(B,0,255);
  1216.         }
  1217.         cp += 3*w+toskew;
  1218.         pp += fromskew;
  1219.     }
  1220. }
  1221. #undef LumaBlue
  1222. #undef LumaGreen
  1223. #undef LumaRed
  1224. #undef CLAMP
  1225. #undef Code2V
  1226.  
  1227. /*
  1228.  * 8-bit packed YCbCr samples => RGB
  1229.  */
  1230. static void
  1231. putcontig8bitYCbCrtile(cp, pp, Map, w, h, fromskew, toskew)
  1232.     register byte *cp;
  1233.     register u_char *pp;
  1234.     register RGBvalue *Map;
  1235.     u_long w, h;
  1236.     int fromskew, toskew;
  1237. {
  1238.     u_int Coff = YCbCrVertSampling * YCbCrHorizSampling;
  1239.     byte *tp;
  1240.     u_long x;
  1241.  
  1242.     /* XXX adjust fromskew */
  1243.     while (h >= YCbCrVertSampling) {
  1244.         tp = cp;
  1245.         for (x = w; x >= YCbCrHorizSampling; x -= YCbCrHorizSampling) {
  1246.             putRGBContigYCbCrClump(tp, pp,
  1247.                 YCbCrHorizSampling, YCbCrVertSampling,
  1248.                 w, Coff, 0, toskew);
  1249.             tp += 3*YCbCrHorizSampling;
  1250.             pp += Coff+2;
  1251.         }
  1252.         if (x > 0) {
  1253.             putRGBContigYCbCrClump(tp, pp,
  1254.                 x, YCbCrVertSampling,
  1255.                 w, Coff, YCbCrHorizSampling - x, toskew);
  1256.             pp += Coff+2;
  1257.         }
  1258.         cp += YCbCrVertSampling*(3*w + toskew);
  1259.         pp += fromskew;
  1260.         h -= YCbCrVertSampling;
  1261.     }
  1262.     if (h > 0) {
  1263.         tp = cp;
  1264.         for (x = w; x >= YCbCrHorizSampling; x -= YCbCrHorizSampling) {
  1265.             putRGBContigYCbCrClump(tp, pp, YCbCrHorizSampling, h,
  1266.                 w, Coff, 0, toskew);
  1267.             tp += 3*YCbCrHorizSampling;
  1268.             pp += Coff+2;
  1269.         }
  1270.         if (x > 0)
  1271.             putRGBContigYCbCrClump(tp, pp, x, h,
  1272.                 w, Coff, YCbCrHorizSampling - x, toskew);
  1273.     }
  1274. }
  1275.  
  1276. /*
  1277.  * Select the appropriate conversion routine for packed data.
  1278.  */
  1279. static tileContigRoutine
  1280. pickTileContigCase(Map)
  1281.     RGBvalue* Map;
  1282. {
  1283.     tileContigRoutine put = 0;
  1284.  
  1285.     switch (photometric) {
  1286.     case PHOTOMETRIC_RGB:
  1287.         put = (bitspersample == 8 ?
  1288.             putRGBcontig8bittile : putRGBcontig16bittile);
  1289.         break;
  1290.     case PHOTOMETRIC_PALETTE:
  1291.         switch (bitspersample) {
  1292.         case 8:    put = put8bitcmaptile; break;
  1293.         case 4: put = put4bitcmaptile; break;
  1294.         case 2: put = put2bitcmaptile; break;
  1295.         case 1: put = put1bitcmaptile; break;
  1296.         }
  1297.         break;
  1298.     case PHOTOMETRIC_MINISWHITE:
  1299.     case PHOTOMETRIC_MINISBLACK:
  1300.         switch (bitspersample) {
  1301.         case 8:    put = putgreytile; break;
  1302.         case 4: put = put4bitbwtile; break;
  1303.         case 2: put = put2bitbwtile; break;
  1304.         case 1: put = put1bitbwtile; break;
  1305.         }
  1306.         break;
  1307.     case PHOTOMETRIC_YCBCR:
  1308.         switch (bitspersample) {
  1309.         case 8: put = putcontig8bitYCbCrtile; break;
  1310.         }
  1311.         break;
  1312.     }
  1313.     if (put == 0)
  1314.         TIFFError(filename, "Can not handle format");
  1315.     return (put);
  1316. }
  1317.  
  1318. /*
  1319.  * Select the appropriate conversion routine for unpacked data.
  1320.  *
  1321.  * NB: we assume that unpacked single channel data is directed
  1322.  *     to the "packed routines.
  1323.  */
  1324. static tileSeparateRoutine
  1325. pickTileSeparateCase(Map)
  1326.     RGBvalue* Map;
  1327. {
  1328.     tileSeparateRoutine put = 0;
  1329.  
  1330.     switch (photometric) {
  1331.     case PHOTOMETRIC_RGB:
  1332.         put = (bitspersample == 8 ?
  1333.             putRGBseparate8bittile : putRGBseparate16bittile);
  1334.         break;
  1335.     }
  1336.     if (put == 0)
  1337.         TIFFError(filename, "Can not handle format");
  1338.     return (put);
  1339. }
  1340.